package org.imlinker.launcher;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

public class Launcher {

	public static void main(String[] args) {

		// 初始化
		String command = "java -jar  ";
		String linkerJarPath = "";
		String path = "";

		// Judge whether it is UNIX like system. and get the absolute path to
		// avoid run program
		String osName = System.getProperty("os.name");
		String temp = Launcher.class.getResource("").toString();
		// Get jarName
		int index = temp.indexOf(".jar");
		int start = index - 1;
		while (Character.isLetter(temp.charAt(start))) {
			start--;
		}
		String jarName = temp.substring(start + 1, index + 4);
		System.out.println(jarName);

		if (osName.startsWith("Linux")) {
			temp = temp.substring(temp.indexOf("/"), temp.indexOf(jarName));
		} else if (osName.startsWith("Windows")) {
			temp = temp.substring(temp.indexOf("file:") + 5, temp
					.indexOf(jarName));
		} else {
			System.exit(0);
		}
		path = path + temp;

		// utf-8 解码
		try {
			path = java.net.URLDecoder.decode(path, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		// get another .jar file;
		File dir = new File(path);
		File[] files = dir.listFiles();
		String exeJarName = null;
		for (File f : files) {
			if (f.getName().endsWith(".jar")
					&& !f.getName().startsWith(jarName)) {
				exeJarName = f.getName();
				break;
			}
		}
		if (exeJarName == null) {
			System.out.println("no exefile");
			System.exit(0);
		}

		linkerJarPath = path + exeJarName;

		// 获取插件列表
		String pluginDirPath = path + "plugin" + File.separator;
		File[] plugins = new File(pluginDirPath).listFiles();
		StringBuffer pluginNames = new StringBuffer("");
		for (File plugin : plugins) {
			if (plugin.getAbsolutePath().endsWith(".jar")) {
				pluginNames.append("plugin/" + plugin.getName() + " ");
			}
		}

		// 获取外在库列表
		String libDirPath = path + "lib" + File.separator;
		File[] libs = new File(libDirPath).listFiles();
		StringBuffer libNames = new StringBuffer("");
		for (File lib : libs) {
			if (lib.getAbsolutePath().endsWith(".jar")) {
				libNames.append("lib/" + lib.getName() + " ");
			}
		}

		// 修改Linker.jar文件，以支持插件.jar
		try {
			// 获得manifest信息，并修改Class-Path选项
			JarFile jarFile = new JarFile(linkerJarPath);
			Manifest manifest = jarFile.getManifest();
			if (manifest == null) {
				manifest = new Manifest();
			}

			Attributes attributes = manifest.getMainAttributes();
			attributes.putValue("Class-Path", pluginNames.toString()
					+ libNames.toString());

			// 复制jarFile
			String backupFile = linkerJarPath + "back";
			FileInputStream copyInput = new FileInputStream(linkerJarPath);
			FileOutputStream copyOutput = new FileOutputStream(backupFile);

			byte[] buffer = new byte[4096];
			int s;
			while ((s = copyInput.read(buffer)) > -1) {
				copyOutput.write(buffer, 0, s);
			}
			copyOutput.flush();
			copyOutput.close();
			copyInput.close();

			// 生成修改manifest.mf之后的imLinker.jar
			JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(
					linkerJarPath), manifest);
			JarInputStream jarIn = new JarInputStream(new FileInputStream(
					backupFile));

			byte[] buf = new byte[4096];
			JarEntry entry;
			while ((entry = jarIn.getNextJarEntry()) != null) {

				if ("META-INF/MANIFEST.MF".equals(entry.getName()))
					continue;

				jarOut.putNextEntry(entry);
				int read;
				while ((read = jarIn.read(buf)) != -1) {
					jarOut.write(buf, 0, read);
				}
				jarOut.closeEntry();
			}
			jarOut.flush();
			jarOut.close();
			jarIn.close();

			// 删除imLinker.jarback
			File file = new File(backupFile);
			if (file.exists()) {
				file.delete();
			}

		} catch (IOException e1) {
			e1.printStackTrace();
		}

		// 执行
		try {
			if (System.getProperty("os.name").startsWith("Linux")) {
				Runtime runtime = Runtime.getRuntime();
				String[] commands = new String[] { "java", "-jar",
						path + exeJarName };
				runtime.exec(commands);
			} else {
				path = path.substring(1);
				command = command + "\"" + path + exeJarName + "\"";
				System.out.println(command);
				Runtime.getRuntime().exec(command);
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}
